package top.suyarong.ftbqsync.listener;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import top.suyarong.ftbqsync.FTBQSync;
import top.suyarong.ftbqsync.data.FtbMapper;
import top.suyarong.ftbqsync.data.entity.FtbQuestSync;
import top.suyarong.ftbqsync.timer.DataSyncTask;
import top.suyarong.ftbqsync.utils.AstralSorceryUtil;
import top.suyarong.ftbqsync.utils.FTBQuestUtil;
import top.suyarong.ftbqsync.utils.LogUtil;
import top.suyarong.ftbqsync.utils.TaskPool;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class PlayerDataListener implements Listener {

    private static final FtbMapper mapper = FtbMapper.getInstance();

    private static final LogUtil log = LogUtil.getInstance();

    private static final TaskPool executor = TaskPool.getInstance();

    private static final FTBQSync plugin = FTBQSync.getInstance();


    public PlayerDataListener() {
        mapper.createTable();
        log.debug(plugin, "数据库初始化完毕");
    }

    @EventHandler
    private void onPlayerLogin(PlayerLoginEvent e) {
        Player player = e.getPlayer();
        log.message(player, "&e&l正在同步任务数据,同步完成前请勿退出,以免任务出现回档");
        String playerName = player.getName();
        DataSyncTask.lock.put(playerName, player);
        Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
            FtbQuestSync ftbQuestSync = executor.runTask(this::getPlayerData, player, 5, TimeUnit.SECONDS);
            if (Objects.isNull(ftbQuestSync)) return;
            DataSyncTask.taskMap.put(player, ftbQuestSync);
        });
    }


    public FtbQuestSync getPlayerData(Player player) {
        String playerName = player.getName();
        int i = 1;
        while (i <= 3) {
            log.info(plugin, "&2正在获取玩家 {} 数据, 当前为第 {} 次尝试", playerName, i);
            if (!mapper.checkPlayerExist(player)) data2Sql(player);

            FtbQuestSync ftbQuestSync = executor.runTask(mapper::getPlayerData, player, 1, TimeUnit.SECONDS);
            if (Objects.nonNull(ftbQuestSync)) return ftbQuestSync;
            i++;
        }
        DataSyncTask.lock.remove(playerName);
        log.warn(plugin, "获取玩家 {} 数据失败, 已经尝试 {} 次", playerName, i);
        player.kickPlayer("§c获取数据失败,请重新登录,多次失败请联系管理员");
        return null;
    }

    @EventHandler
    private void onPlayerExit(PlayerQuitEvent e) {
        Player player = e.getPlayer();
        lockPlayerData(player);
        updatePlayerData(player);
    }

    // 获取服务端玩家任务数据存入sql
    private void data2Sql(Player player) {
        byte[] playerQuestNbtData = FTBQuestUtil.getPlayerQuestNbtData(player);
        byte[] playerAstralData = AstralSorceryUtil.getData(player);
        String playerName = player.getName();
        mapper.insertNewPlayer(FtbQuestSync.builder()
                .playerName(playerName)
                .ftbData(playerQuestNbtData)
                .astralData(playerAstralData)
                .build());
    }

    // 锁定数据
    public void lockPlayerData(Player player) {
        String playerName = player.getName();
        mapper.lockPlayer(FtbQuestSync.builder().playerName(playerName).build());
    }

    // 更新玩家数据
    public void updatePlayerData(Player player) {
        byte[] playerQuestNbtData = FTBQuestUtil.getPlayerQuestNbtData(player);
        byte[] playerAstralData = AstralSorceryUtil.getData(player);
        String playerName = player.getName();
        mapper.updatePlayer(FtbQuestSync.builder()
                .playerName(playerName)
                .ftbData(playerQuestNbtData)
                .astralData(playerAstralData)
                .build());
    }



}
